package com.jingdianjichi.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.jingdianjichi.auth.common.enums.AuthUserStatusEnum;
import com.jingdianjichi.auth.common.enums.IsDeletedFlagEnum;
import com.jingdianjichi.auth.domain.constants.AuthConstant;
import com.jingdianjichi.auth.domain.convert.AuthUserBOConverter;
import com.jingdianjichi.auth.domain.entity.AuthUserBo;
import com.jingdianjichi.auth.domain.redis.RedisUtil;
import com.jingdianjichi.auth.domain.service.AuthUserDomainService;
import com.jingdianjichi.auth.infra.basic.entity.*;
import com.jingdianjichi.auth.infra.basic.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {
    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthUserRoleService authUserRoleService;

    @Resource
    private AuthRoleService authRoleService;
    @Resource
    private AuthPermissionService authPermissionService;

    @Resource
    private AuthRolePermissionService authRolePermissionService;


    private  String salt="123";

    @Resource
    private RedisUtil redisUtil;

    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";

    private static final String LOGIN_PREFIX = "loginCode";



    /**
     * 注册
     *
     * @param authUserBo
     */
    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public Boolean register(AuthUserBo authUserBo) {
        //校验用户是否存在
        AuthUser exitAuthUser=new AuthUser();
        exitAuthUser.setUserName(authUserBo.getUserName());
        List<AuthUser> exitUser=authUserService.queryByCondition(exitAuthUser);
        if(exitUser.size()>0){
            return  true;
        }
        AuthUser authUser= AuthUserBOConverter.INSTANCE.convertBOtoEntity(authUserBo);
        if (StringUtils.isNotBlank(authUser.getPassword())) {
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(), salt));
        }

        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
        authUser.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        Integer count=authUserService.insert(authUser);

        //建立一个初步的角色关联
        AuthRole authRole=new AuthRole();
        authRole.setRoleKey(AuthConstant.NORMAL_USER);
      AuthRole roleResult=  authRoleService.queryByCondition(authRole);
      Long roleId=roleResult.getId();
      Long userId=authUser.getId();
        AuthUserRole authUserRole=new AuthUserRole();
        authUserRole.setRoleId(roleId);
        authUserRole.setUserId(userId);
        authUserRole.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUserRoleService.insert(authUserRole);

        String roleKey=redisUtil.buildKey(authRolePrefix,authUser.getUserName());
         List<AuthRole> roleList=new LinkedList<>();
         roleList.add(authRole);
         redisUtil.set(roleKey,new Gson().toJson(roleList));

        AuthRolePermission authRolePermission=new AuthRolePermission();
        authRolePermission.setRoleId(roleId);
        List<AuthRolePermission> rolePermissionList=authRolePermissionService.queryByCondition(authRolePermission);
        List<Long> permissionIdList = rolePermissionList.stream()
                .map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
        //根据roleId查权限
        List<AuthPermission> permissionList = authPermissionService.queryByRoleList(permissionIdList);
        String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        redisUtil.set(permissionKey, new Gson().toJson(permissionList));


        return count>0;
    }

    /**
     * 更新用户信息
     *
     * @param authUserBo
     */
    @Override
    public Boolean delete(AuthUserBo authUserBo) {
     AuthUser authUser=new AuthUser();
     authUser.setId(authUserBo.getId());
        authUser.setIsDeleted(IsDeletedFlagEnum.DELETED.getCode());
        Integer count=authUserService.update(authUser);
        return count>0;
    }

    @Override
    public SaTokenInfo doLogin(String validCode) {
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        String openId = redisUtil.get(loginKey);
        if (StringUtils.isBlank(openId)) {
            return null;
        }
        AuthUserBo authUserBO = new AuthUserBo();
        authUserBO.setUserName(openId);
        this.register(authUserBO);
        StpUtil.login(openId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return tokenInfo;

    }

    @Override
    public AuthUserBo getUserInfo(AuthUserBo authUserBo) {
        AuthUser authUser=new AuthUser();
        authUser.setUserName(authUserBo.getUserName());
        List<AuthUser> userList=authUserService.queryByCondition(authUser);
        if(CollectionUtils.isEmpty(userList)){
            return  new AuthUserBo();
        }
        AuthUser user=userList.get(0);
        return AuthUserBOConverter.INSTANCE.convertEntityToBO(user);
    }

    /**
     * 删除用户信息
     *
     * @param authUserBo
     */
    @Override
    public Boolean update(AuthUserBo authUserBo) {
      AuthUser authUser=AuthUserBOConverter.INSTANCE.convertBOtoEntity(authUserBo);
      Integer count= authUserService.update(authUser);
      return count>0;


    }


}




